﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
using AutoMapper;
using Core;
using IglooCoder.Commons.WcfNhibernate;
using Infrastucture;
using NHibernate.Transform;
using WcfService1.DTO;
using Omu.ValueInjecter;

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "InventoryService" in code, svc and config file together.
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [NHibernateContext]
    public class InventoryService : IInventoryService
    {
        private readonly InventoryRepository InventoryRep;
        private readonly InventoryWarehouseRepository _iwRepository;
        private readonly WarehouseRepository _wareouseReposiory;
        private readonly MutasiStokRepository mutasiStokRep;
        private readonly HppRepository hppRep;
        private BtbElseRepository btbElseRepository;
        private PurchaseInvoiceRepository purchaseInvoiceRepository;
        private InventoryAdjustmentRepository inventoryAdjustmentRepository;
        private SalesReturnRepository salesReturnRepository;
        private SalesInvoiceRepository salesInvoiceRepository;
        public InventoryService()
        {
            var sesssion = new WcfSessionStorage();
            InventoryRep = new InventoryRepository(sesssion);
            _iwRepository = new InventoryWarehouseRepository(sesssion);
            _wareouseReposiory = new WarehouseRepository(sesssion);
            mutasiStokRep = new MutasiStokRepository(sesssion);
            hppRep = new HppRepository(sesssion);
            btbElseRepository = new BtbElseRepository(sesssion);
            purchaseInvoiceRepository = new PurchaseInvoiceRepository(sesssion);
            inventoryAdjustmentRepository = new InventoryAdjustmentRepository(sesssion);
            salesReturnRepository = new SalesReturnRepository(sesssion);
            salesInvoiceRepository = new SalesInvoiceRepository(sesssion);
        }

        #region IInventoryService Members

        public void DoWork()
        {
        }


        public List<InventoryDTO> GetInventories(int page, out int recordCount, string sortProperty = null,
                                                 string sortType = "ASC")
        {
         
            var inventoryDtos = new List<InventoryDTO>();
            IList<Inventory> Inventories = new List<Inventory>();

            if (string.IsNullOrEmpty(sortProperty))
            {
                Inventories = InventoryRep.GetDataPaged(page, 30);
            }
            else
            {
                if (sortProperty.ToLower() == "group")
                    sortProperty = "g.GroupName";
                if (sortProperty.ToLower() == "subgroup")
                    sortProperty = "sg.SubGroupName";
                if (sortProperty.ToLower() == "item")
                    sortProperty = "it.ItemName";
                Inventories = InventoryRep.GetDataPaged(page, 30, sortProperty, sortType);
            }


            inventoryDtos = Inventories.Select((x) => new InventoryDTO
                                                          {
                                                              SerialNumber = x.SerialNumber,
                                                              NoBundle = x.NoBundle,
                                                              Description = x.Description,
                                                              Panjang = x.Panjang ?? 0,
                                                              Lebar = x.Lebar ?? 0,
                                                              Tinggi = x.InventoryWarehouses.FirstOrDefault().Sheet,
                                                              Item =
                                                                  new ItemDTO
                                                                      {
                                                                          ItemId = x.Item.ItemId,
                                                                          ItemName = x.Item.ItemName,
                                                                          IsRounded = x.Item.IsRounded,
                                                                          IsStock = x.Item.IsStock
                                                                      },
                                                              QtyPack = x.QtyPack ?? 0,
                                                              QtyUnit = x.InventoryWarehouses.FirstOrDefault().Qty,
                                                              KodeWarehouse = x.InventoryWarehouses.FirstOrDefault().KodeWarehouse,
                                                              KodePallet = x.InventoryWarehouses.FirstOrDefault().KodePallet,
                                                              SatuanPack =
                                                                  new SatuanDTO
                                                                      {
                                                                          KodeSatuan =
                                                                              x.SatuanPack == null
                                                                                  ? ""
                                                                                  : x.SatuanPack.KodeSatuan
                                                                      },
                                                              SatuanUnit =
                                                                  new SatuanDTO
                                                                      {
                                                                          KodeSatuan = x.SatuanUnit == null
                                                                                     ? ""
                                                                                     : x.SatuanUnit.KodeSatuan,
                                                                          Pengali = x.SatuanUnit == null
                                                                                  ? 1
                                                                                  : x.SatuanUnit.Pengali,
                                                                      },
                                                              Group = x.Item.SubGroup.Group.GroupName,
                                                              Subgroup = x.Item.SubGroup.SubGroupName,
                                                              Warehouses = new ObservableCollection<WarehouseDTO>(from w in x.InventoryWarehouses
                                                                           select new WarehouseDTO() { KodeWarehouse = w.KodeWarehouse, Qty = w.Qty,Sheet = w.Sheet,KodePallet = w.KodePallet}),
                                                              UnitPrice = x.UnitPrice ?? 0,
                                                              TotalValue = (x.InventoryWarehouses.Sum(w=>w.Qty) * x.UnitPrice) ?? 0,
                                                              CoaHpp =  x.CoaHpp,
                                                              CoaInventory = x.CoaInventory,
                                                              CoaSales = x.CoaSales,
                                                              CoaSalesReturn = x.CoaSalesReturn
 
                                                          }).ToList();

            recordCount = (int) InventoryRep.RecordCount;
            return inventoryDtos;
        }

        public void SaveInventory(InventoryDTO inventoryDto)
        {
            InventoryRep.ExecuteTransactionNative(()=>
                                                      {
                                                          Inventory inventory = InventoryRep.GetDataOne(x => x.SerialNumber == inventoryDto.SerialNumber);
                                                          var user = new User();
                                                          if (inventory == null)
                                                          {
                                                              inventory = new Inventory();
                                                              inventoryDto.created_date = DateTime.Now;
                                                              //AutoMapper.Mapper.Map(inventoryDto.created_by, user);
                                                              //inventoryDto.modified_by = null;
                                                          }
                                                          else
                                                          {
                                                              inventoryDto.modified_date = DateTime.Now;
                                                              //AutoMapper.Mapper.Map(inventoryDto.modified_by, user);
                                                          }
                                                          Mapper.Map(inventoryDto, inventory);
                                                          InventoryRep.SaveOrUpdate(inventory);
                                                      });
           
        }

        public void DeleteInventory(InventoryDTO inventoryDto)
        {
            var inventory = new Inventory();
            Mapper.Map(inventoryDto, inventory);
            InventoryRep.Delete(inventory);
        }


        public List<InventoryDTO> GetInventoryByCriteria(Dictionary<String, Object> criteria, string expression,
                                                         int page, out int recordCount)
        {
            var inventoryDtos = new List<InventoryDTO>();

            IList<Inventory> Inventories = InventoryRep.GetDataPaged(criteria, expression, page, 30);
           inventoryDtos = Inventories.Select((x) => new InventoryDTO
                                                          {
                                                              SerialNumber = x.SerialNumber,
                                                              NoBundle = x.NoBundle,
                                                              Description = x.Description,
                                                              Panjang = x.Panjang ?? 0,
                                                              Lebar = x.Lebar ?? 0,
                                                              Tinggi = x.InventoryWarehouses.FirstOrDefault().Sheet,
                                                              Item =
                                                                  new ItemDTO
                                                                      {
                                                                          ItemId = x.Item.ItemId,
                                                                          ItemName = x.Item.ItemName,
                                                                          IsRounded = x.Item.IsRounded,
                                                                          IsStock = x.Item.IsStock
                                                                      },
                                                              QtyPack = x.QtyPack ?? 0,
                                                              QtyUnit = x.InventoryWarehouses.FirstOrDefault().Qty,
                                                              KodeWarehouse = x.InventoryWarehouses.FirstOrDefault().KodeWarehouse,
                                                              KodePallet = x.InventoryWarehouses.FirstOrDefault().KodePallet,
                                                              SatuanPack =
                                                                  new SatuanDTO
                                                                      {
                                                                          KodeSatuan =
                                                                              x.SatuanPack == null
                                                                                  ? ""
                                                                                  : x.SatuanPack.KodeSatuan
                                                                      },
                                                              SatuanUnit =
                                                                  new SatuanDTO
                                                                      {
                                                                          KodeSatuan = x.SatuanUnit == null
                                                                                   ? ""
                                                                                   : x.SatuanUnit.KodeSatuan,
                                                                          Pengali = x.SatuanUnit == null
                                                                                  ? 1
                                                                                  : x.SatuanUnit.Pengali,
                                                                      },
                                                              Group = x.Item.SubGroup.Group.GroupName,
                                                              Subgroup = x.Item.SubGroup.SubGroupName,
                                                              Warehouses = new ObservableCollection<WarehouseDTO>(from w in x.InventoryWarehouses
                                                                                                                  select new WarehouseDTO() { KodeWarehouse = w.KodeWarehouse, Qty = w.Qty, Sheet = w.Sheet,KodePallet = w.KodePallet }),
                                                              UnitPrice = x.UnitPrice ?? 0,
                                                              TotalValue = (x.InventoryWarehouses.Sum(w => w.Qty) * x.UnitPrice) ?? 0,
                                                              CoaHpp = x.CoaHpp,
                                                              CoaInventory = x.CoaInventory,
                                                              CoaSales = x.CoaSales,
                                                              CoaSalesReturn = x.CoaSalesReturn
 
                                                          }).ToList();

            recordCount = (int) InventoryRep.RecordCount;
            return inventoryDtos;
        }


        public List<InventoryDTO> GetInventoryByCriteriaFull(Dictionary<String, Object> criteria, string expression,
                                                             int page, out int recordCount)
        {
            var inventoryDtos = new List<InventoryDTO>();

            inventoryDtos = InventoryRep.GetDataByCriteriaFull(criteria, expression, page, 30);
            //inventoryDtos = Inventories.Select((x) => new InventoryDTO
            //                                              {
            //                                                  SerialNumber = x.SerialNumber,
            //                                                  NoBundle = x.NoBundle,
            //                                                  Description = x.Description,
            //                                                  Panjang = x.Panjang ?? 0,
            //                                                  Lebar = x.Lebar ?? 0,
            //                                                  Tinggi = x.Tinggi ?? 0,
            //                                                  Item =
            //                                                      new ItemDTO
            //                                                          {
            //                                                              ItemId = x.Item.ItemId,
            //                                                              ItemName = x.Item.ItemName,
            //                                                              IsRounded = x.Item.IsRounded ,
            //                                                              IsStock = x.Item.IsStock
            //                                                          },
            //                                                  QtyPack = x.QtyPack ?? 0,
            //                                                  QtyUnit = x.QtyUnit ?? 0,
            //                                                  SatuanPack =
            //                                                      new SatuanDTO
            //                                                          {
            //                                                              KodeSatuan =
            //                                                                  x.SatuanPack == null
            //                                                                      ? ""
            //                                                                      : x.SatuanPack.KodeSatuan
            //                                                          },
            //                                                  SatuanUnit =
            //                                                      new SatuanDTO
            //                                                          {
            //                                                              KodeSatuan =  x.SatuanUnit == null
            //                                                                      ? ""
            //                                                                      : x.SatuanUnit.KodeSatuan,
            //                                                              Pengali = x.SatuanUnit == null
            //                                                                      ? 1
            //                                                                      : x.SatuanUnit.Pengali,
            //                                                          },
            //                                                  Group = x.Item.SubGroup.Group.GroupName,
            //                                                  Subgroup = x.Item.SubGroup.SubGroupName,
            //                                                  Warehouses = new ObservableCollection<WarehouseDTO>(from w in x.InventoryWarehouses
            //                                                                                                      select new WarehouseDTO() { KodeWarehouse = w.KodeWarehouse, Qty = w.Qty, Sheet = w.Sheet, KodePallet = w.KodePallet }),
            //                                                  CoaHpp = x.CoaHpp,
            //                                                  CoaInventory = x.CoaInventory,
            //                                                  CoaSales = x.CoaSales,
            //                                                  CoaSalesReturn = x.CoaSalesReturn
            //                                              }).ToList();

            recordCount = (int) InventoryRep.RecordCount;

            if (inventoryDtos.Count > 1000)
                return inventoryDtos.Take(1000).OrderBy(x => x.Item.ItemName).ToList();
            else
                return inventoryDtos.OrderBy(x => x.Item.ItemName).ToList();
        }


        public InventoryDTO GetInventory(String kodeInventory)
        {
            Inventory Inventory = InventoryRep.GetDataOne(x => x.SerialNumber == kodeInventory);
            if (Inventory == null) return new InventoryDTO();
            IList<InventoryWarehouse> inventoryWarehouses =
                _iwRepository.GetDataList(x => x.SerialNumber == Inventory.SerialNumber);
            var InventoryDto = new InventoryDTO();
            try
            {
                InventoryDto = Inventory.ConvertToDTO<Inventory, InventoryDTO>();
                InventoryDto.Warehouses = new ObservableCollection<WarehouseDTO>();
                if (Inventory.IsStock)
                {
                    if (inventoryWarehouses.Count < 1) throw new Exception("Barang tidak ada!");
                    foreach (InventoryWarehouse inventoryWarehouse in inventoryWarehouses)
                    {
                        InventoryDto.Warehouses.Add(new WarehouseDTO
                        {
                            KodeWarehouse = inventoryWarehouse.KodeWarehouse,
                            Qty = inventoryWarehouse.Qty,
                            Panjang = inventoryWarehouse.Panjang,
                            Lebar = inventoryWarehouse.Lebar,
                            Sheet = inventoryWarehouse.Sheet,
                            KodePallet = inventoryWarehouse.KodePallet
                        });
                    }
                }
                
            }
            catch (Exception ex)
            {
                return null;
            }

            //InventoryDto.QtyUnit = inventoryWarehouses.FirstOrDefault().Qty;
            //InventoryDto.Tinggi = inventoryWarehouses.FirstOrDefault().Sheet;
            return InventoryDto;
        }

        public InventoryDTO GetInventoryByWarehouse(String kodeInventory, string KodeWarehouse)
        {
            Inventory Inventory = InventoryRep.GetDataOne(x => x.SerialNumber == kodeInventory);
            if (Inventory == null) return new InventoryDTO();
            IList<InventoryWarehouse> inventoryWarehouses =
                _iwRepository.GetDataList(x => x.SerialNumber == Inventory.SerialNumber && x.KodeWarehouse == KodeWarehouse);
            var InventoryDto = new InventoryDTO();
            try
            {
                InventoryDto = Inventory.ConvertToDTO<Inventory, InventoryDTO>();
                InventoryDto.Warehouses = new ObservableCollection<WarehouseDTO>();
                if (Inventory.IsStock)
                {
                    if (inventoryWarehouses.Count < 1) throw new Exception("Barang tidak ada!");
                    foreach (InventoryWarehouse inventoryWarehouse in inventoryWarehouses)
                    {
                        InventoryDto.Warehouses.Add(new WarehouseDTO
                        {
                            KodeWarehouse = inventoryWarehouse.KodeWarehouse,
                            Qty = inventoryWarehouse.Qty,
                            Panjang = inventoryWarehouse.Panjang,
                            Lebar = inventoryWarehouse.Lebar,
                            Sheet = inventoryWarehouse.Sheet,
                            KodePallet = inventoryWarehouse.KodePallet
                        });
                    }
                }

            }
            catch (Exception ex)
            {
                return null;
            }

            //InventoryDto.QtyUnit = inventoryWarehouses.FirstOrDefault().Qty;
            //InventoryDto.Tinggi = inventoryWarehouses.FirstOrDefault().Sheet;
            return InventoryDto;
        }

        public List<InventoryDTO> GetInventoryBySerial(String kodeInventory)
        {
            IList<Inventory> InventoryList = InventoryRep.GetDataList(x => x.SerialNumber.Contains(kodeInventory));
            var inventoryDtos = new List<InventoryDTO>();

            foreach (Inventory inventory in InventoryList)
            {
                var inventoryDto = new InventoryDTO();
                inventoryDto = inventory.ConvertToDTO<Inventory, InventoryDTO>();
                inventoryDtos.Add(inventoryDto);
            }
            return inventoryDtos;
        }


        public List<InventoryWarehouseDTO> GetInventoryWarehouseList(string serialNumber)
        {
            IList<InventoryWarehouse> res = _iwRepository.GetDataList(x => x.SerialNumber == serialNumber);
            List<InventoryWarehouseDTO> results = (from i in res
                                                   select new InventoryWarehouseDTO
                                                              {
                                                                  Inventory =
                                                                      InventoryRep.GetDataOne(
                                                                          x => x.SerialNumber == i.SerialNumber).
                                                                      ConvertToDTO<Inventory, InventoryDTO>(),
                                                                  Warehouse =
                                                                      _wareouseReposiory.GetDataOne(
                                                                          X => X.KodeWarehouse == i.KodeWarehouse).
                                                                      ConvertToDTO<Warehouse, WarehouseDTO>(),
                                                                  Qty = i.Qty,
                                                                  Sheet = i.Sheet
                                                              }).ToList();
            return results;
        }

        public bool SaveInventoryWarehouse(List<InventoryWarehouseDTO> inventoryWarehouses)
        {
            bool res = true;
            try
            {
                foreach (InventoryWarehouseDTO inventoryWarehouseDto in inventoryWarehouses)
                {
                    InventoryWarehouse iw =
                        inventoryWarehouseDto.ConvertToDTO<InventoryWarehouseDTO, InventoryWarehouse>();
                    _iwRepository.SaveOrUpdate(iw);
                }
            }
            catch (Exception ex)
            {
                res = false;
            }

            return res;
        }

        public InventoryWarehouseDTO GetQtyOnHand(string serialNumber, string kodeWarehouse)
        {
            InventoryWarehouse res =
                _iwRepository.GetDataOne(x => x.SerialNumber == serialNumber && x.KodeWarehouse == kodeWarehouse);
            if (res == null) return new InventoryWarehouseDTO();
            var result = new InventoryWarehouseDTO
                             {
                                 Inventory =
                                     InventoryRep.GetDataOne(x => x.SerialNumber == res.SerialNumber).ConvertToDTO
                                     <Inventory, InventoryDTO>(),
                                 Warehouse =
                                     _wareouseReposiory.GetDataOne(X => X.KodeWarehouse == res.KodeWarehouse).
                                     ConvertToDTO<Warehouse, WarehouseDTO>(),
                                 Qty = res.Qty,
                                 Sheet = res.Sheet
                             };
            return result;
        }


        public List<WarehouseDTO> GetWarehouses(string serialNumber)
        {
            IList<InventoryWarehouse> res = _iwRepository.GetDataList(x => x.SerialNumber == serialNumber);
            List<WarehouseDTO> results = (from i in res
                                          select new WarehouseDTO
                                                     {
                                                         KodeWarehouse = i.KodeWarehouse
                                                     }).ToList();
            return results;
        }

        public void ImportInventory(List<InventoryDTO> inventoryDtos)
        {
            List<Inventory> inventories = new List<Inventory>();
            
            foreach (var inventoryDto in inventoryDtos)
            {
                var inventory = new Inventory();
                inventory.SerialNumber = inventoryDto.SerialNumber;
                inventory.NoBundle = inventoryDto.NoBundle;
                inventory.Description = inventoryDto.Description;
                inventory.QtyPack = inventoryDto.QtyPack;
                inventory.QtyUnit = inventoryDto.QtyUnit;
                inventory.UnitPrice = inventoryDto.UnitPrice;
                inventory.Panjang = inventoryDto.Panjang;
                inventory.Lebar = inventoryDto.Lebar;
                inventory.Tinggi = inventoryDto.Tinggi;
                inventory.KodeMasuk = inventoryDto.KodeMasuk;
                inventory.Item = new Item() {ItemId = inventoryDto.Item.ItemId};
                inventory.SatuanPack = new Satuan() {KodeSatuan = inventoryDto.SatuanPack.KodeSatuan};
                inventory.SatuanUnit = new Satuan() {KodeSatuan = inventoryDto.SatuanUnit.KodeSatuan};
                inventory.UnitPrice = inventoryDto.UnitPrice;
                inventory.IsStock = inventoryDto.IsStock;
                inventory.InventoryWarehouses = new List<InventoryWarehouse>();
                var inventoryWarehouse = new InventoryWarehouse();
                inventoryWarehouse.SerialNumber = inventory.SerialNumber;
                inventoryWarehouse.KodeWarehouse = inventoryDto.Warehouses.FirstOrDefault().KodeWarehouse;
                inventoryWarehouse.Sheet = inventoryDto.Warehouses.FirstOrDefault().Sheet;
                inventoryWarehouse.Qty = inventoryDto.Warehouses.FirstOrDefault().Qty;
                inventoryWarehouse.KodePallet = inventoryDto.Warehouses.FirstOrDefault().KodePallet;
                inventory.InventoryWarehouses.Add(inventoryWarehouse);
                inventories.Add(inventory);
            }

            InventoryRep.InsertRange(inventories);
        }


        public List<InventoryDTO> GetInventoryList(List<InventoryDTO> inventoryDtos)
        {
            List<InventoryDTO> inventories = new List<InventoryDTO>();
            foreach (var inventoryDto in inventoryDtos)
            {
                var inventory = GetInventory(inventoryDto.SerialNumber);
                inventories.Add(inventory);
            }
            return inventories;
        }


        public List<InventoryDTO> GetInventoryListbyWarehouse(List<InventoryDTO> inventoryDtos,string kodeWarehouse)
        {
            var inventories = new List<InventoryDTO>();
            List<string> serials = inventoryDtos.Select(inventoryDto => inventoryDto.SerialNumber).ToList();
            var inventoryList =  InventoryRep.GetInventoryList(serials);
            foreach (var inventory in inventoryList)
            {
                var inventoryDTO = (InventoryDTO) new InventoryDTO().InjectFrom(inventory);
                inventoryDTO.Panjang = inventory.Panjang.Value;
                inventoryDTO.Lebar = inventory.Lebar.Value;
                inventoryDTO.QtyPack = inventory.QtyPack.Value;
                inventoryDTO.QtyUnit = inventory.QtyUnit.Value;
                inventoryDTO.Item = (ItemDTO) new ItemDTO().InjectFrom(inventory.Item);
                inventoryDTO.SatuanPack = (SatuanDTO) new SatuanDTO().InjectFrom(inventory.SatuanPack);
                inventoryDTO.SatuanUnit = (SatuanDTO) new SatuanDTO().InjectFrom(inventory.SatuanUnit);
                inventoryDTO.Warehouses = new ObservableCollection<WarehouseDTO>();
                if (inventory.IsStock)
                {
                    if (inventory.InventoryWarehouses.Count < 1) throw new Exception("Barang tidak ada!");
                    foreach (var inventoryWarehouse in inventory.InventoryWarehouses.Where(x=>x.KodeWarehouse==kodeWarehouse))
                    {
                        inventoryDTO.Warehouses.Add(new WarehouseDTO
                        {
                            KodeWarehouse = inventoryWarehouse.KodeWarehouse,
                            Qty = inventoryWarehouse.Qty,
                            Panjang = inventoryWarehouse.Panjang,
                            Lebar = inventoryWarehouse.Lebar,
                            Sheet = inventoryWarehouse.Sheet,
                            KodePallet = inventoryWarehouse.KodePallet
                        });
                    }
                }
                inventories.Add(inventoryDTO);}
            return inventories;
        }

        public void AdjustStok()
        {
            InventoryRep.ExecuteTransactionNative(()=>
                                                      {
                                                          mutasiStokRep.AdjustStokBySystem();  
                                                      });
           
        }


        public void  AdjustHpp()
        {
            //var inventories = InventoryRep.FetchAll().Take(10).ToList();
            InventoryRep.ExecuteTransactionNative(()=>
                                                      {
                                                          var t = mutasiStokRep.Session.CreateSQLQuery("Delete from Hpp").ExecuteUpdate();

                                                          var mutasiList =
                                                              mutasiStokRep.Session.CreateSQLQuery(
                                                                  "Select * from MutasiStok Where Type<>'MutasiWarehouse' AND SerialNumber like'%RECON%' Order By SerialNumber,TglMutasi")
                                                                  .SetResultTransformer(Transformers.AliasToBean(typeof(MutasiStok)))
                                                                  .List<MutasiStok>();

                                                          foreach (var mutasiStok in mutasiList)
                                                          {
                                                              var hpp = CreateHpp(mutasiStok);
                                                              if (hpp.HppAkhir == 0) continue;
                                                              hppRep.SaveOrUpdate(hpp);
                                                          }
                                                      });
           
        }

        public Hpp CreateHpp(MutasiStok mutasiStok)
        {
            var hpp = new Hpp();
            hpp.Tipe = mutasiStok.Type;

            var hppBefore = hppRep.FindLastHpp(mutasiStok.SerialNumber, mutasiStok.TglMutasi);
            var inventory = InventoryRep.GetDataOne(x => x.SerialNumber == mutasiStok.SerialNumber);

            if (hppBefore.HppAkhir == 0 && mutasiStok.Type == "SaldoAwal")
            {
                hppBefore.HppAkhir = (decimal)inventory.UnitPrice;
                hppBefore.QtyAkhir = mutasiStokRep.GetQtyOnHand(mutasiStok.SerialNumber, mutasiStok.TglMutasi);
            }
          
            hpp.Tipe = mutasiStok.Type;
            hpp.ReffNumber = mutasiStok.ReferenceNumber;
           
            hpp.SerialNumber = mutasiStok.SerialNumber;
            hpp.Tanggal = mutasiStok.TglMutasi;
            hpp.HppAwal = hppBefore.HppAkhir;
            hpp.QtyAwal = hppBefore.QtyAkhir;
            hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;

            if (mutasiStok.QtyMasuk > 0)
            {
                hpp.QtyIn = mutasiStok.QtyMasuk;
                if (mutasiStok.Type == "BtbElse")
                {
                    var btbElse = btbElseRepository.GetDataOne(x => x.NoBtb == mutasiStok.ReferenceNumber);
                    hpp.HppIn = btbElse.BtbDetails.FirstOrDefault(x => x.NoLog == mutasiStok.SerialNumber).Price;
                }
                else if (mutasiStok.Type == "BTB")
                {
                    var pi = purchaseInvoiceRepository.GetPurchaseInvoiceByBtb(mutasiStok.ReferenceNumber);
                    hpp.HppIn = pi.PurchaseInvoiceDetails.FirstOrDefault(x => x.Inventory.SerialNumber == mutasiStok.SerialNumber).Price;
                    hpp.ReffNumber = pi.PINo;
                }
                else if (mutasiStok.Type == "InventoryAdjustment")
                {
                    if (mutasiStok.QtyMasuk > 0)
                    {
                        var adj = inventoryAdjustmentRepository.GetDataOne(x => x.NoAdj == mutasiStok.ReferenceNumber);
                        hpp.HppIn = adj.InventoryAdjustmentDetails.FirstOrDefault(x => x.Inventory.SerialNumber == mutasiStok.SerialNumber).Price;
                    }

                }
                else if (mutasiStok.Type == "SalesReturn")
                {
                    var sr = salesReturnRepository.GetDataOne(x => x.SRNo == mutasiStok.ReferenceNumber);
                    hpp.HppIn = sr.SalesReturnDetails.FirstOrDefault(x => x.Inventory.SerialNumber == mutasiStok.SerialNumber).Price;
                }else
                {
                    hpp.HppIn = hppBefore.HppAkhir;
                }


                hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
            }
            else
            {
                hpp.QtyOut = mutasiStok.QtyKeluar;
                hpp.HppOut = hpp.HppAwal;
                hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                if (mutasiStok.Type == typeof(DeliveryOrder).ToString())
                {
                    var si = salesInvoiceRepository.GetDataOne(x => x.DONo == mutasiStok.ReferenceNumber);
                    hpp.ReffNumber = si.SINo;
                }
            }

            hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
            hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
            hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
            return hpp;
        }



        
        public void UpdateHpp(List<InventoryDTO> inventoryDtos)
        {
            IList<Inventory> inventories = new List<Inventory>();
            IList<Hpp> hpps = new BindingList<Hpp>();
            foreach (var inventoryDto in inventoryDtos)
            {
                inventories.Add(new Inventory() { SerialNumber = inventoryDto.SerialNumber, UnitPrice = inventoryDto.UnitPrice });
                var inventory = InventoryRep.GetDataOne(x => x.SerialNumber == inventoryDto.SerialNumber);
                var hpp = new Hpp();
                hpp.SerialNumber = inventoryDto.SerialNumber;
                hpp.Tanggal = new DateTime(2011, 01, 01);
                hpp.ReffNumber = "SaldoAwal";
                hpp.Tipe = "SaldoAwal";
                hpp.HppAwal = 0;
                hpp.QtyAwal = 0;
                hpp.AmountAwal = 0;
                hpp.QtyIn = inventory.QtyUnit ?? 0;
                hpp.HppIn = inventoryDto.UnitPrice;
                hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
                hpp.QtyOut = 0;
                hpp.HppOut = 0;
                hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                hpps.Add(hpp);
            }

            InventoryRep.ExecuteTransactionNative(() =>
                                                      {
                                                          InventoryRep.UpdateHpp(inventories);
                                                          hppRep.SaveHppList(hpps);
                                                      });
        }

        #endregion
    }
}